﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;

namespace CommonWFLibrary
{
    /// <summary>
    /// Simple persistance object that provides services
    /// to cache the long running activity state to a disk file.
    /// After creating the obect, just pass the save and restore
    /// methods as arguments. Don't use this if you are dealing with
    /// more than one runtime!!
    /// </summary>
	public class LongRunningActivityBinaryPersister
	{
        private FileInfo _file;

        /// <summary>
        /// Create the persistancy service. Save data for this service
        /// in the given data flow.
        /// </summary>
        /// <param name="dataFile"></param>
        public LongRunningActivityBinaryPersister(FileInfo dataFile)
        {
            _file = dataFile;
        }

        /// <summary>
        /// Save the file obj to the disk
        /// </summary>
        /// <param name="obj">Object graph to save; null if we should delete the file</param>
        public void Save(object obj)
        {
            ///
            /// If the object graph is null, then get rid of the cache file.
            /// 

            if (obj == null)
            {
                _file.Refresh();
                if (_file.Exists)
                {
                    _file.Delete();
                }
                return;
            }

            ///
            /// Save the data to the file.
            /// 

            FileInfo newFile = new FileInfo(_file.FullName + "-temp");
            using (FileStream f = newFile.Create())
            {
                BinaryFormatter fmt = new BinaryFormatter();
                fmt.Serialize(f, obj);
                f.Close();
            }
            _file.Refresh();
            if (_file.Exists)
            {
                newFile.Replace(_file.FullName, _file.FullName + "-old");
            }
            else
            {
                newFile.MoveTo(_file.FullName);
            }
        }

        /// <summary>
        /// Restore the file from the disk.
        /// </summary>
        /// <returns></returns>
        public object Restore()
        {
            _file.Refresh();
            if (!_file.Exists)
            {
                return null;
            }
            using (FileStream f = _file.Open(FileMode.Open))
            {
                BinaryFormatter bmt = new BinaryFormatter();
                object result = bmt.Deserialize(f);
                f.Close();
                return result;
            }
        }
	}
}
